/****************************************************************************
*
* Copyright (c) 2023  C*Core -   All Rights Reserved
*
* THIS SOFTWARE IS DISTRIBUTED "AS IS, " AND ALL WARRANTIES ARE DISCLAIMED,
* INCLUDING MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
* PROJECT     : CCFC2011BC
* DESCRIPTION : CCFC2011BC FLEXLIN demo c file
* HISTORY     : Initial version.
* @file     lin_demo.c
* @version  1.1
* @date     2023 - 02 - 20
* @brief    Initial version.
*
*****************************************************************************/
#include "lin_demo.h"
#include "lin_lld.h"
#include "console.h"
#include "sys.h"
#include "common.h"
#include "intc_lld.h"

/*
 * Used by master to read 4 bytes from slave.
 *
 * Filter is set in slave node, so for this message
 * direction is Transmit (from a slave point of view).
 */
#define LIN_MSG_1      37
#define LIN_MSG_1_SIZE  4

/*
 * Used by master to send 4 bytes to slave.
 *
 * Filter is set in slave node, so for this message
 * direction is Receive (from a slave point of view).
 */
#define LIN_MSG_2      38
#define LIN_MSG_2_SIZE  4

/*
 * Used by master to read 8 bytes from slave.
 *
 * Filter is set in slave node, so for this message
 * direction is Transmit (from a slave point of view).
 */
#define LIN_MSG_3      45
#define LIN_MSG_3_SIZE  8

/**
 * @brief   Structures defining the filters configuration for lin_filter_37_4_Transmit.
 */
static LinFilter Filter_37_4_Transmit_List = {
    37,
    4,
    LIN_DIRECTION_TRANSMIT,
    LIN_ENHANCED_CHECKSUM,
    LIN_LIST_MODE,
    0
};

/**
 * @brief   Structures defining the filters configuration for lin_filter_38_4_Receive.
 */
static LinFilter Filter_38_4_Receive_List = {
    38,
    4,
    LIN_DIRECTION_RECEIVE,
    LIN_ENHANCED_CHECKSUM,
    LIN_LIST_MODE,
    0
};

/**
 * @brief   Structures defining the filters configuration for lin_filter_45_8_Transmit.
 */
static LinFilter Filter_45_8_Transmit_List = {
    45,
    8,
    LIN_DIRECTION_TRANSMIT,
    LIN_ENHANCED_CHECKSUM,
    LIN_LIST_MODE,
    0
};

/**
 * @brief   Structures defining the filters configuration for lin_filter_46_8_Receive.
 */
static LinFilter Filter_46_8_Receive_List = {
    46,
    8,
    LIN_DIRECTION_RECEIVE,
    LIN_ENHANCED_CHECKSUM,
    LIN_LIST_MODE,
    0
};

/**
 * @brief   Structures defining the no_filters configuration for lin_filter_37_4_Receive.
 */
static No_LinFilter No_Filter_37_4_Receive_List = {
    37,
    4,
    LIN_DIRECTION_TRANSMIT,
    LIN_ENHANCED_CHECKSUM
};

/**
 * @brief   Structures defining the no_filters configuration for lin_filter_37_4_Receive.
 */
static No_LinFilter No_Filter_38_4_Receive_List = {
    38,
    4,
    LIN_DIRECTION_RECEIVE,
    LIN_ENHANCED_CHECKSUM
};

/**
 * @brief   Structure defining the LIN configuration "lin_master".
 */
static const LinConfig lin_config_lin_master = {
    20000,
    LIN_MODE_MASTER,
    CCFC20xx_LIN_API_MODE_SYNCHRONOUS,
    master_tx_callback,
    master_rx_callback,
    NULL,
    NULL,
    0,
    0,
    NULL
};

static const LinConfig lin_config_lin_master_dma = {
    20000,
    LIN_MODE_MASTER,
    CCFC20xx_LIN_API_MODE_SYNCHRONOUS,
    master_tx_callback,
    master_rx_callback,
    NULL,
    NULL,
    0,
    1,
    NULL
};

static LinFilter *lin_Filters_lin_slave[] = {
    &Filter_37_4_Transmit_List,
    &Filter_38_4_Receive_List,
    &Filter_45_8_Transmit_List,
    &Filter_46_8_Receive_List,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL
};

/**
 * @brief   Structure defining the LIN configuration "lin_slave".
 */
static const LinConfig lin_config_lin_slave_filter = {
    20000,
    LIN_MODE_SLAVE,
    CCFC20xx_LIN_API_MODE_SYNCHRONOUS,
    slave_tx_callback,
    slave_rx_callback,
    lin_Filters_lin_slave,
    NULL,
    0,
    0,
    NULL
};

static const LinConfig lin_config_lin_slave_filter_dma = {
    20000,
    LIN_MODE_SLAVE,
    CCFC20xx_LIN_API_MODE_SYNCHRONOUS,
    slave_tx_callback,
    slave_rx_callback,
    lin_Filters_lin_slave,
    NULL,
    0,
    1,
    NULL
};

/**
 * @brief   Structure defining the LIN configuration "lin_slave".
 */
static const LinConfig lin_config_lin_slave_nofilter_ID37 = {
    20000,
    LIN_MODE_SLAVE,
    CCFC20xx_LIN_API_MODE_SYNCHRONOUS,
    slave_tx_callback,
    slave_rx_callback,
    NULL,
    &No_Filter_37_4_Receive_List,
    0,
    0,
    NULL
};

static const LinConfig lin_config_lin_slave_nofilter_ID38 = { /* PRQA S 0779 */
    20000u,
    LIN_MODE_SLAVE,
    CCFC20xx_LIN_API_MODE_SYNCHRONOUS,
    slave_tx_callback,
    slave_rx_callback,
    NULL,
    &No_Filter_38_4_Receive_List,
    0,
    0,
    NULL
};

static void lld_write(const uint8_t *buffer, uint16_t len)
{
    uint8_t i = 0;
    const uint8_t *t_buffer;
    t_buffer = buffer;
    for (i = 0; i < len; i++)
    {
        Uart_Send_Char(*t_buffer);
        t_buffer++;
    }
}

static void write_msg(const uint8_t *msg, uint16_t len)
{
    lld_write(msg, len);
}

static void write_new_line(void)
{
    char nl[2];
    nl[0] = '\n';
    nl[1] = '\r';
    write_msg((uint8_t *)nl, 2);
}

static void write_lin_msg(uint8_t sender, uint8_t direction, uint8_t msg_id, const uint8_t *msg, uint16_t len)
{
    char buf[16];
    uint8_t p;

    if (sender == (uint8_t)LIN_MODE_MASTER)
    {
        cc_memcpy((uint8_t *)buf, (uint8_t *)"MASTER, ", 8);
    }
    else
    {
        cc_memcpy((uint8_t *)buf, (uint8_t *)"SLAVE,  ", 8);
    }
    write_msg((uint8_t *)buf, 8);

    buf[0] = (char)direction;
    buf[1] = ' ';
    buf[2] = ' ';
    write_msg((uint8_t *)buf, 3);

    /*
    * Following code could have been written more efficiently
    * but keep MISRA check happy...
    */
    p = msg_id / 10U;
    p = 48U + p;
    buf[0] = (char)p;
    p = (uint8_t)(48U + msg_id - ((msg_id / 10U) * 10U));
    buf[1] = (char)p;

    buf[2] = ' ';
    buf[3] = ' ';
    write_msg((uint8_t *)buf, 4);

    write_msg(msg, len);

    write_new_line();
}

static uint32_t master_tx_callback(const LinDriver *ldp, uint8_t idMessage,  uint8_t *buffer, uint16_t len)/* PRQA S 3673 */
{ 
    write_lin_msg((uint8_t)ldp->config->mode, (uint8_t)'T', idMessage, buffer, len);
    return 0;
}

static uint32_t master_rx_callback(const LinDriver *ldp, uint8_t idMessage,  const uint8_t *buffer, uint16_t len)
{
    write_lin_msg((uint8_t)ldp->config->mode, (uint8_t) 'R', idMessage, buffer, len);
    return 0;
}

static uint32_t slave_tx_callback(const LinDriver *ldp, uint8_t idMessage,  uint8_t *buffer, uint16_t len)
{
    uint8_t i;
    uint32_t ret;
    uint8_t  *ptemp = NULL;
    ptemp = buffer;
    /* Fill in data buffer */
    switch (idMessage)
    {
        case LIN_MSG_1:
        for (i = 0; i < len; i++)
        {
            ptemp[i] = (uint8_t)'A' + i;
        }
        ret = len;
        break;
        case LIN_MSG_3:
        for (i = 0; i < len; i++)
        {
            ptemp[i] = (uint8_t)'M' + i;
        }
        ret = len;
        break;
        default:
            ret = 0;
            break;
    }

    write_lin_msg((uint8_t)ldp->config->mode, (uint8_t)'T', idMessage, ptemp, len);

    return ret;
}

static uint32_t slave_rx_callback(const LinDriver *ldp, uint8_t idMessage, const uint8_t *buffer, uint16_t len)
{
    write_lin_msg((uint8_t)ldp->config->mode, (uint8_t)'R', idMessage, buffer, len);
    return 0;
}


/*******************************************************************************
 * @brief      This case shall be test the master receive by interrupt.
 * @param[in]  None
 * @param[out] None
 * @retval     None
 * @notapi
*******************************************************************************/
static void Lin_Demo_Test_Case1(void)
{
    uint8_t rx_buffer[LIN_MSG_1_SIZE];
    uint8_t count = 0u;

    /** init**/
    Lin_Gpio_Init(&LD4, LIN_GPIO_DEFAULT);

    Lin_Lld_Init(&LD4,  &lin_config_lin_master);

    Lin_Init_IrqIsrEnable(&LD4);

     /* Application main loop.*/
     for (count = 0u ; count < 10u ; count++)
     {
         /* Master asks for data associated to MSG #1 */
         (void)Lin_Master_Receive(&LD4, LIN_MSG_1, rx_buffer, LIN_MSG_1_SIZE);
    }
}

/*******************************************************************************
 * @brief      This case shall be test the Master Tramsmit by interrupt.
 * @param[in]  None
 * @param[out] None
 * @retval     None
 * @notapi
*******************************************************************************/
static void Lin_Demo_Test_Case2(void)
{
    uint8_t tx_buffer[LIN_MSG_2_SIZE] = {0X44, 0X45, 0X46, 0X17};

    uint8_t count = 0u;

    Lin_Gpio_Init(&LD4, LIN_GPIO_DEFAULT);

    Lin_Lld_Init(&LD4,  &lin_config_lin_master);

    Lin_Init_IrqIsrEnable(&LD4);

     /* Application main loop.*/
     for (count = 0u ; count < 10u ; count++)
     {
         /* Master sends data associated to MSG #2  */
         (void) Lin_Master_Transmit(&LD4, LIN_MSG_2, tx_buffer, LIN_MSG_2_SIZE);

         (void)delay_ms(500);
    }
}

/*******************************************************************************
 * @brief      This case shall be test the Slave receive which used filter by interrupt 
 * @param[in]  None
 * @param[out] None
 * @retval     None
 * @notapi
*******************************************************************************/
static void Lin_Demo_Test_Case3(void)
{
    uint8_t rx_buffer[LIN_MSG_2_SIZE] = {0};

    uint8_t count = 0u;

    Lin_Gpio_Init(&LD1, LIN_GPIO_MUX);

    Lin_Lld_Init(&LD1, &lin_config_lin_slave_filter);

    Lin_Init_IrqIsrEnable(&LD1);

     /* Application main loop.*/
     for (count = 0u ; count < 10u ; count++)
     {
         (void)Lin_Slave_Receive(&LD1, rx_buffer, LIN_MSG_2_SIZE);
     }
}

/*******************************************************************************
 * @brief      This case shall be test the Slave receive which not used filter 
 *             by interrupt 
 * @param[in]  None
 * @param[out] None
 * @retval     None
 * @notapi
*******************************************************************************/
static void Lin_Demo_Test_Case4(void)
{
    uint8_t rx_buffer[LIN_MSG_2_SIZE];

    uint8_t count = 0u;

    Lin_Gpio_Init(&LD4, LIN_GPIO_DEFAULT);

    Lin_Lld_Init(&LD4,  &lin_config_lin_slave_nofilter_ID38);

    Lin_Init_IrqIsrEnable(&LD4);

     /* Application main loop.*/
     for (count = 0u ; count < 10u ; count++)
     {
         (void)Lin_Slave_Receive(&LD4, rx_buffer, LIN_MSG_2_SIZE);
     }
}

/*******************************************************************************
 * @brief      This case shall be test the Slave transmit which used filter 
 *             by interrupt 
 * @param[in]  None
 * @param[out] None
 * @retval     None
 * @notapi
*******************************************************************************/
static void Lin_Demo_Test_Case5(void)
{
    uint8_t tx_buffer[LIN_MSG_1_SIZE] = {0x43, 0x44, 0x45, 0x46};

    uint8_t count = 0u;

    Lin_Gpio_Init(&LD1, LIN_GPIO_MUX); ;

    Lin_Lld_Init(&LD1, &lin_config_lin_slave_filter);

    Lin_Init_IrqIsrEnable(&LD1);

     /* Application main loop.*/
     for (count = 0u ; count < 10u ; count++)
     {
         Lin_Slave_Transmit(&LD1, LIN_MSG_1, tx_buffer, LIN_MSG_1_SIZE);
     }
}

/*******************************************************************************
 * @brief      This case shall be test the Slave transmit which not used filter 
 *             by interrupt 
 * @param[in]  None
 * @param[out] None
 * @retval     None
 * @notapi
*******************************************************************************/
static void Lin_Demo_Test_Case6(void)
{
    uint8_t tx_buffer[LIN_MSG_1_SIZE] = {0x43, 0x44, 0x45, 0x46};

    uint8_t count = 0u;

    Lin_Gpio_Init(&LD4, LIN_GPIO_DEFAULT);

    Lin_Lld_Init(&LD4,  &lin_config_lin_slave_nofilter_ID37);

    Lin_Init_IrqIsrEnable(&LD4);

     /* Application main loop.*/
     for (count = 0u ; count < 10u ; count++)
     {
         Lin_Slave_Transmit(&LD4, LIN_MSG_1, tx_buffer, LIN_MSG_1_SIZE);
     }
}

/*******************************************************************************
 * @brief      This case shall be test the Master transmit by polling 
 * @param[in]  None
 * @param[out] None
 * @retval     None
 * @notapi
*******************************************************************************/
static void Lin_Demo_Test_Case7(void)
{
    const uint8_t tx_buffer[LIN_MSG_3_SIZE] = {0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18};

    uint8_t count = 0u;

    Lin_Gpio_Init(&LD4, LIN_GPIO_DEFAULT);

    Lin_Lld_Init(&LD4,  &lin_config_lin_master);

    for (count = 0u ; count < 10u ; count++)
    {
        Lin_Master_Polling_Transmit(&LD4, LIN_MSG_3, tx_buffer, LIN_MSG_3_SIZE);
    }
}

/*******************************************************************************
 * @brief      This case shall be test the Master receive by polling 
 * @param[in]  None
 * @param[out] None
 * @retval     None
 * @notapi
*******************************************************************************/
static void Lin_Demo_Test_Case8(void)
{
    uint8_t rx_buffer[LIN_MSG_3_SIZE] = {0};

    uint8_t count = 0u;

    Lin_Gpio_Init(&LD4, LIN_GPIO_DEFAULT);

    Lin_Lld_Init(&LD4,  &lin_config_lin_master);

    for (count = 0u ; count < 10u ; count++)
    {
        Lin_Master_Polling_Receive(&LD4, LIN_MSG_3, rx_buffer, LIN_MSG_3_SIZE);
    }
}

/*******************************************************************************
 * @brief      This case shall be test the slave receive which used filter by polling 
 * @param[in]  None
 * @param[out] None
 * @retval     None
 * @notapi
*******************************************************************************/
static void Lin_Demo_Test_Case9(void)
{
    uint8_t rx_buffer[LIN_MSG_2_SIZE] = {0};

    uint8_t count = 0u;

    Lin_Gpio_Init(&LD1, LIN_GPIO_MUX);

    Lin_Lld_Init(&LD1, &lin_config_lin_slave_filter);

    for (count = 0u ; count < 10u ; count++)
    {
        Lin_Slave_Polling_Receive(&LD1, LIN_MSG_2, rx_buffer, LIN_MSG_2_SIZE);
    }
}


/*******************************************************************************
 * @brief      This case shall be test the slave receive which not used filter by polling 
 * @param[in]  None
 * @param[out] None
 * @retval     None
 * @notapi
*******************************************************************************/
static void Lin_Demo_Test_Case10(void)
{
    uint8_t rx_buffer[LIN_MSG_2_SIZE] = {0};

    uint8_t count = 0u;

    Lin_Gpio_Init(&LD4, LIN_GPIO_DEFAULT);

    Lin_Lld_Init(&LD4,  &lin_config_lin_slave_nofilter_ID38);

    for (count = 0u ; count < 10u ; count++)
    {
        Lin_Slave_Polling_Receive(&LD4, LIN_MSG_2, rx_buffer, LIN_MSG_2_SIZE);
    }
}

/*******************************************************************************
 * @brief      This case shall be test the slave transmit which used filter by polling 
 * @param[in]  None
 * @param[out] None
 * @retval     None
 * @notapi
*******************************************************************************/
static void Lin_Demo_Test_Case11(void)
{
    const uint8_t tx_buffer[LIN_MSG_1_SIZE] = {0x11, 0x12, 0x13, 0x14};

    uint8_t count = 0u;

    Lin_Gpio_Init(&LD1, LIN_GPIO_MUX);

    Lin_Lld_Init(&LD1, &lin_config_lin_slave_filter);

    for (count = 0u ; count < 200u ; count++)
    {
        Lin_Slave_Polling_Transmit(&LD1, LIN_MSG_1, tx_buffer, LIN_MSG_1_SIZE);
    }
}

/*******************************************************************************
 * @brief      This case shall be test the slave transmit which not used filter 
 *             by polling 
 * @param[in]  None
 * @param[out] None
 * @retval     None
 * @notapi
*******************************************************************************/
static void Lin_Demo_Test_Case12(void)
{
    const uint8_t tx_buffer[LIN_MSG_1_SIZE] = {0x11, 0x12, 0x13, 0x14};

    uint8_t count = 0u;

    Lin_Gpio_Init(&LD4, LIN_GPIO_DEFAULT);

    Lin_Lld_Init(&LD4,  &lin_config_lin_slave_nofilter_ID37);

    for (count = 0u ; count < 10u ; count++)
    {
        Lin_Slave_Polling_Transmit(&LD4, LIN_MSG_1, tx_buffer, LIN_MSG_1_SIZE);
    }
}

/*******************************************************************************
 * @brief      This function shall be the master transmit by DMA
 * @param[in]  None
 * @param[out] None
 * @retval     None
 * @notapi
*******************************************************************************/
static void Lin_Demo_Test_Case13(void)
{
    uint8_t tx_buffer[8u] = {0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48};

    uint8_t count = 0u;

    Lin_Gpio_Init(&LD1, LIN_GPIO_MUX);

    Lin_Lld_Init(&LD1,  &lin_config_lin_master_dma);

    Lin_Init_IrqIsrEnable(&LD1);

     /* Application main loop.*/
     for (count = 0u ; count < 10u ; count++)
     {
         /* Master sends data associated to MSG #2  */
         Lin_Master_Transmit_DMA(&LD1, LIN_MSG_2, tx_buffer, 8);
         (void)delay_ms(10);
    }
}

/*******************************************************************************
 * @brief      This function shall be the master receive by DMA
 * @param[in]  None
 * @param[out] None
 * @retval     None
 * @notapi
*******************************************************************************/
static void Lin_Demo_Test_Case14(void)
{
    uint8_t rx_buffer[LIN_MSG_1_SIZE];

    uint8_t count = 0u;
    /** init**/
    Lin_Gpio_Init(&LD1, LIN_GPIO_MUX);

    Lin_Lld_Init(&LD1,  &lin_config_lin_master_dma);

    Lin_Init_IrqIsrEnable(&LD1);

     /* Application main loop.*/
     for (count = 0u ; count < 10u ; count++)
     {
         /* Master asks for data associated to MSG #1 */
         (void)Lin_Master_Receive_DMA(&LD1, LIN_MSG_1, rx_buffer, LIN_MSG_1_SIZE);
    }
}

/*******************************************************************************
 * @brief      This function shall be the slave transmit by DMA
 * @param[in]  None
 * @param[out] None
 * @retval     None
 * @notapi
*******************************************************************************/
static void Lin_Demo_Test_Case15(void)
{
    uint8_t tx_buffer[LIN_MSG_1_SIZE] = {0x44, 0x45, 0x46, 0x47};

    uint8_t count = 0u;

    Lin_Gpio_Init(&LD1, LIN_GPIO_MUX);

    Lin_Lld_Init(&LD1,  &lin_config_lin_slave_filter_dma);

    Lin_Init_IrqIsrEnable(&LD1);

     /* Application main loop.*/
     for (count = 0u ; count < 10u ; count++)
     {
         Lin_Slave_Transmit_DMA(&LD1, LIN_MSG_1, tx_buffer, LIN_MSG_1_SIZE);
     }
}

/*******************************************************************************
 * @brief      This function shall be the slave receive by DMA
 * @param[in]  None
 * @param[out] None
 * @retval     None
 * @notapi
*******************************************************************************/
static void Lin_Demo_Test_Case16(void)
{
    uint8_t rx_buffer[LIN_MSG_2_SIZE] = {0};

    uint8_t count = 0u;

    Lin_Gpio_Init(&LD1, LIN_GPIO_MUX);

    Lin_Lld_Init(&LD1,  &lin_config_lin_slave_filter_dma);

    Lin_Init_IrqIsrEnable(&LD1);

     /* Application main loop.*/
      for (count = 0u ; count < 10u ; count++)
     {
         (void)Lin_Slave_Receive_DMA(&LD1, rx_buffer, LIN_MSG_2_SIZE);
     }
}

/*******************************************************************************
 * @brief      This function shall be the low power test
 * @param[in]  None
 * @param[out] None
 * @retval     None
 * @notapi
*******************************************************************************/
static void Lin_Demo_Test_Case17(void)
{
    (void)delay_ms(2000);

    Lin_LLD_Lowper_exit(&LD1);
    Lin_LLD_Lowper_exit(&LD2);
    Lin_LLD_Lowper_exit(&LD3);
    Lin_LLD_Lowper_exit(&LD4);
    Lin_LLD_Lowper_exit(&LD5);
    (void)delay_ms(2000);
    (void)delay_ms(2000);
    (void)delay_ms(2000);
    (void)delay_ms(2000);

    Lin_LLD_Lowper_enter(&LD1);
    Lin_LLD_Lowper_enter(&LD2);
    Lin_LLD_Lowper_enter(&LD3);
    Lin_LLD_Lowper_enter(&LD4);
    Lin_LLD_Lowper_enter(&LD5);

    (void)delay_ms(2000);
    (void)delay_ms(2000);

    Lin_LLD_Lowper_exit(&LD1);
    Lin_LLD_Lowper_exit(&LD2);
    Lin_LLD_Lowper_exit(&LD3);
    Lin_LLD_Lowper_exit(&LD4);
    Lin_LLD_Lowper_exit(&LD5);
    Lin_LLD_Lowper_exit(&LD6);
}

/*******************************************************************************
 * @brief      This function shall be the Traverse test
 * @param[in]  None
 * @param[out] None
 * @retval     None
 * @notapi
*******************************************************************************/

static void Lin_Demo_Test_Case18(void)
{
    uint8_t i = 0;
    uint8_t rx_buffer[LIN_MSG_2_SIZE] = {0};
    uint8_t const test_buffer[LIN_MSG_2_SIZE] = {0x41, 0x42, 0x43, 0x44};

    Lin_Gpio_Init(&LD2, LIN_GPIO_DEFAULT);
    Lin_Gpio_Init(&LD3, LIN_GPIO_DEFAULT);
    Lin_Gpio_Init(&LD4, LIN_GPIO_DEFAULT);
    Lin_Gpio_Init(&LD5, LIN_GPIO_DEFAULT);
    Lin_Gpio_Init(&LD6, LIN_GPIO_DEFAULT);
    Lin_Gpio_Init(&LD7, LIN_GPIO_DEFAULT);
    Lin_Gpio_Init(&LD8, LIN_GPIO_DEFAULT);
    

    Lin_Lld_Init(&LD2,  &lin_config_lin_slave_nofilter_ID38);
    Lin_Lld_Init(&LD3,  &lin_config_lin_slave_nofilter_ID38);
    Lin_Lld_Init(&LD4,  &lin_config_lin_slave_nofilter_ID38);
    Lin_Lld_Init(&LD5,  &lin_config_lin_slave_nofilter_ID38);
    Lin_Lld_Init(&LD6,  &lin_config_lin_slave_nofilter_ID38);
    Lin_Lld_Init(&LD7,  &lin_config_lin_slave_nofilter_ID38);
    Lin_Lld_Init(&LD8,  &lin_config_lin_slave_nofilter_ID38);

    for (i = 0u ; i < 7u ; i++)
    {
        if (i == (uint8_t)0)
        {
            for (; ;)
            {
                Lin_Slave_Polling_Receive(&LD2, LIN_MSG_2, rx_buffer, LIN_MSG_2_SIZE);

                (void)delay_ms(500);

                write_new_line();

                if (cc_memcmp(rx_buffer, test_buffer, LIN_MSG_2_SIZE) == 0u)
                {
                    (void)cc_memset(rx_buffer, 0, LIN_MSG_2_SIZE);
                    break;
                }
            }
        }
        if (i == (uint8_t)1)
        {
            for (; ;)
            {
                Lin_Slave_Polling_Receive(&LD3, LIN_MSG_2, rx_buffer, LIN_MSG_2_SIZE);

                (void)delay_ms(500);

                write_new_line();

                if (cc_memcmp(rx_buffer, test_buffer, LIN_MSG_2_SIZE) == 0u)
                {
                    (void)cc_memset(rx_buffer, 0, LIN_MSG_2_SIZE);
                    break;
                }
            }
        }
        if (i == (uint8_t)2)
        {
            for (; ;)
            {
                Lin_Slave_Polling_Receive(&LD4, LIN_MSG_2, rx_buffer, LIN_MSG_2_SIZE);

                (void)delay_ms(500);

                write_new_line();

                if (cc_memcmp(rx_buffer, test_buffer, LIN_MSG_2_SIZE) == 0u)
                {
                    (void)cc_memset(rx_buffer, 0, LIN_MSG_2_SIZE);
                    break;
                }
            }
        }
        if (i == (uint8_t)3)
        {
            for (; ;)
            {
                Lin_Slave_Polling_Receive(&LD5, LIN_MSG_2, rx_buffer, LIN_MSG_2_SIZE);

                (void)delay_ms(500);

                write_new_line();

                if (cc_memcmp(rx_buffer, test_buffer, LIN_MSG_2_SIZE) == 0u)
                {
                    (void)cc_memset(rx_buffer, 0, LIN_MSG_2_SIZE);
                    break;
                }
            }
        }
        if (i == (uint8_t)4)
        {
            for (; ;)
            {
                Lin_Slave_Polling_Receive(&LD6, LIN_MSG_2, rx_buffer, LIN_MSG_2_SIZE);

                (void)delay_ms(500);

                write_new_line();

                if (cc_memcmp(rx_buffer, test_buffer, LIN_MSG_2_SIZE) == 0u)
                {
                    (void)cc_memset(rx_buffer, 0, LIN_MSG_2_SIZE);
                    break;
                }
            }
        }
        if (i == (uint8_t)5)
        {
            for (; ;)
            {
                Lin_Slave_Polling_Receive(&LD7, LIN_MSG_2, rx_buffer, LIN_MSG_2_SIZE);

                (void)delay_ms(500);

                write_new_line();

                if (cc_memcmp(rx_buffer, test_buffer, LIN_MSG_2_SIZE) == 0u)
                {
                    (void)cc_memset(rx_buffer, 0, LIN_MSG_2_SIZE);
                    break;
                }
            }
        }
        if (i == (uint8_t)6)
        {
            for (; ;)
            {
                Lin_Slave_Polling_Receive(&LD8, LIN_MSG_2, rx_buffer, LIN_MSG_2_SIZE);

                (void)delay_ms(500);

                write_new_line();

                if (cc_memcmp(rx_buffer, test_buffer, LIN_MSG_2_SIZE) == 0u)
                {
                    (void)cc_memset(rx_buffer, 0, LIN_MSG_2_SIZE);
                    break;
                }
            }
        }
    }
}

/*******************************************************************************
 * @brief      This function shall be the extend frame transmit test
 * @param[in]  None
 * @param[out] None
 * @retval     None
 * @notapi
*******************************************************************************/
static void Lin_Demo_Test_Case19(void)
{
    const uint8_t tx_buffer[24] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
                           0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
    uint8_t count = 0u;

    Lin_Gpio_Init(&LD1, LIN_GPIO_MUX);

    Lin_Lld_Init(&LD1,  &lin_config_lin_master);

    Lin_Init_IrqIsrEnable(&LD1);

    for (count = 0u ; count < 10u ; count++)
    {
       Lin_Master_Polling_Transmit_ExtendFrame(&LD1, LIN_MSG_3, tx_buffer, 24);

       (void)delay_ms(50);

       write_new_line();
    }
}

/* *****************************************************************************
   Function:        void Lin_Demo(void)
   Description:     LIN
   Parameters:      Input:    None
                    Output:   None
   Notes:           date 2022.06
   ******************************************************************************/
void Lin_Demo(void)
{
    INTC_IRQ_Enable();  /* PRQA S 3335*/
    
    /* Function: Master Receive by Interrupt */
#if LIN_CASE1 
    Lin_Demo_Test_Case1();         
#endif

    /* Function: Master Transmit by Interrupt */
#if LIN_CASE2  
    Lin_Demo_Test_Case2();        
#endif

    /* Function: Slave filter Receive by Interrupt */
#if LIN_CASE3   
    Lin_Demo_Test_Case3();
#endif

    /* Function: Slave No filter Receive by Interrupt */
#if LIN_CASE4  
    Lin_Demo_Test_Case4();
#endif

    /* Function: Slave filter Transmit by Interrupt */
#if LIN_CASE5  
    Lin_Demo_Test_Case5();
#endif

    /* Function: Slave No filter Transmit by Interrupt */
#if LIN_CASE6
    Lin_Demo_Test_Case6();
#endif

    /* Function: Master Transmit by Polling */
#if LIN_CASE7  
    Lin_Demo_Test_Case7();               
#endif

    /* Function: Master Receive by Polling */
#if LIN_CASE8  
    Lin_Demo_Test_Case8();                
#endif

    /* Function: Slave filter Receive by Polling */
#if LIN_CASE9  
    Lin_Demo_Test_Case9();          
#endif
    
    /* Function: Slave No filter Receive by Polling */
#if LIN_CASE10  
    Lin_Demo_Test_Case10();       
#endif

    /* Function: Slave Filter Transmit by Polling */
#if LIN_CASE11  
    Lin_Demo_Test_Case11();        
#endif

    /* Function: Slave Transmit by Polling */
#if LIN_CASE12  
    Lin_Demo_Test_Case12();      
#endif
    
    /* Function: Master Transmit by DMA */
#if LIN_CASE13  
    Lin_Demo_Test_Case13();             
#endif

    /* Function: Master Receive by DMA */
#if LIN_CASE14  
    Lin_Demo_Test_Case14();              
#endif

    /* Function: Slave Transmit by DMA */
#if LIN_CASE15  
    Lin_Demo_Test_Case15();              
#endif
    
    /* Function: Slave Receive by DMA */
#if LIN_CASE16  
    Lin_Demo_Test_Case16();               
#endif
    
    /* Function: Low power test */
#if LIN_CASE17  
    Lin_Demo_Test_Case17();
#endif

    /* Function: Traverse test */
#if LIN_CASE18  
    Lin_Demo_Test_Case18();                    
#endif 

    /* Function: Extend Frame test */
#if LIN_CASE19  
    Lin_Demo_Test_Case19();                 
#endif
    
}
